<?php

 /**
  * @package JooS
  * @subpackage CodeGenerator
  */

  require_once "JooS/CodeGenerator/Abstract.php";

  class JooS_CodeGenerator_Class extends JooS_CodeGenerator_Abstract {
    /**
     * @var bool
     */
    private $_final = false;

    /**
     *
     * @var bool
     */
    private $_abstract = false;

    /**
     * @var string
     */
    private $_extendedClass = null;

    /**
     * @var array
     */
    private $_properties = null;

    /**
     * @var array
     */
    private $_methods = null;

    /**
     * @param string $name
     */
    public function __construct($name) {
      parent::__construct($name);

      $this->clearProperties();
      $this->clearMethods();
    }

    /**
     * @return string
     */
    public function compile() {
      $PHPCode = "<?php\n\n" . self::INDENT;

      $extendedClass = $this->getExtendedClass();
      if ($extendedClass) {
        $PHPCode .= "require_once \"" . str_replace("_", "/", $extendedClass) . ".php\";\n\n" . self::INDENT;
      }

      $PHPCode .= $this->isFinal() ? "final " : "";
      $PHPCode .= $this->isAbstract() ? "abstract " : "";
      $PHPCode .= "class " . $this->getName() . " ";

      $PHPCode .= $extendedClass ? "extends " . $extendedClass . " " : "";

      $PHPCode .= "{\n";

      $parts = array();
      for ($i=0; $i<sizeof($this->_properties); $i++)
        $parts[] = $this->_properties[$i]->compile();
      for ($i=0; $i<sizeof($this->_methods); $i++)
        $parts[] = $this->_methods[$i]->compile();

      $PHPCode .= implode("\n", $parts);

      $PHPCode .= self::INDENT . "}\n\n";
      return $PHPCode;
    }

    /**
     * @param string $className
     * @return JooS_CodeGenerator_Class
     */
    public static function newInstance($className) {
      return new self($className);
    }

    /**
     * @param bool $final
     * @return JooS_CodeGenerator_Class
     */
    public function setFinal($final) {
      $this->_final = !!$final;

      return $this;
    }

    /**
     * @return string
     */
    public function isFinal() {
      return $this->_final;
    }

    /**
     * @todo $this->_abstract = !!$abstract;
     * @return JooS_CodeGenerator_Class
     */
    public function setAbstract($abstract) {
      return $this;
    }

    /**
     * @return bool
     */
    public function isAbstract() {
      return $this->_abstract;
    }

    /**
     * @return string
     */
    public function getExtendedClass() {
      return $this->_extendedClass;
    }

    /**
     * @param string $extendedClass
     * @return JooS_CodeGenerator_Class
     */
    public function setExtendedClass($extendedClass) {
      $this->_extendedClass = $extendedClass;
      return $this;
    }

    /**
     * @param JooS_CodeGenerator_Property $property
     * @return JooS_CodeGenerator_Class
     */
    public function addProperty(JooS_CodeGenerator_Property $property) {
      $this->_properties[] = $property;
      return $this;
    }

    /**
     * @return array
     */
    public function getProperties() {
      return $this->_properties;
    }

    /**
     * @return JooS_CodeGenerator_Class
     */
    public function clearProperties() {
      $this->_properties = array();
      return $this;
    }

    /**
     * @param JooS_CodeGenerator_Method $method
     * @return JooS_CodeGenerator_Class
     */
    public function addMethod(JooS_CodeGenerator_Method $method) {
      $this->_methods[] = $method;
      return $this;
    }

    /**
     * @return array
     */
    public function getMethods() {
      return $this->_methods;
    }

    /**
     * @return JooS_CodeGenerator_Class
     */
    public function clearMethods() {
      $this->_methods = array();
      return $this;
    }
  }
